<?php
/**
 * 只能处理一个客户端的连接和数据传输，只有断开后才能处理新的客户端连接
 */
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($sock === false) {
    return "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
} else {
    echo "create tcp_socket OK.\n";
}

$res = socket_bind($sock, '0.0.0.0', 9501);
if ($res === false) {
    return "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
} else {
    echo "bind tcp_socket OK.\n";
}

// backlog 服务器在处理现有连接时可以接受的挂起连接请求的最大数量
// linux 系统一般是 128 或 4096
$res = socket_listen($sock, 5);
if ($res === false) {
    return "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
} else {
    echo "listen tcp_socket OK.\n";
}

while (true) {
    $newSock = socket_accept($sock);
    if ($newSock === false) {
        echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
        break;
    } else {
        echo "accept tcp_socket OK.\n";
    }

    $msg = "Welcome to the PHP Test Server. \n" .
        "To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
    socket_write($newSock, $msg, strlen($msg));

    do {
        if (false === ($buf = socket_read($newSock, 2048, PHP_NORMAL_READ))) {
            echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($newSock)) . "\n";
            break;
        }
        if (!($buf = trim($buf))) {
            continue;
        }
        if ($buf === 'quit') {
            socket_close($newSock);
            break;
        }
        if ($buf === 'shutdown') {
            socket_close($newSock);
            socket_close($sock);
            break 2;
        }
        $talkback = "PHP: You said '$buf'.\n";
        socket_write($newSock, $talkback, strlen($talkback));
        echo "$buf\n";
    } while (true);

    // socket_close($sock);
}


